// 1. sleep函数
function sleep(delay) {
    return new Promise((resolve) => setTimeout(resolve, delay));
};


async function foo() {
    const t0 = Date.now();
    await sleep(5000);
    console.log(Date.now() - t0);
};

// foo();


// 2. 利用平行执行
async function randomDelay(id) {
    // 延迟0-1000ms
    const delay = Math.random() * 1000;
    return new Promise((resolve) => setTimeout(() => {
        console.log(`${id} finished`);
        resolve();
    }, delay));
};

async function bar() {
    const t0 = Date.now();
    await randomDelay(0);
    await randomDelay(1);
    await randomDelay(2);
    await randomDelay(3);
    await randomDelay(4);
    console.log(`${Date.now() - t0}ms elapsed`);
};

async function baz() {
    const t0 = Date.now();
    for (let i = 0; i < 5; i++) {
        await randomDelay(i);
    };
    console.log(`${Date.now() - t0}ms elapsed`);
};

// bar();
// baz();

async function kob() {
    const t0 = Date.now();

    const p0 = randomDelay(0); 
    const p1 = randomDelay(1); 
    const p2 = randomDelay(2); 
    const p3 = randomDelay(3); 
    const p4 = randomDelay(5); 

    await p0;
    await p1;
    await p2;
    await p3;
    await p4;

    console.log(`${Date.now() - t0}ms elapsed`);
};

// kob();

// 3. 串行执行期约
async function addTwo(x) {
    return x+2;
};

async function addThree(x) {
    return x+3;
};

async function addFive(x) {
    return x+5;
};

async function addTen(x) {
    for (const fn of [addTwo, addThree, addFive]) {
        console.log(fn(x))
        x = await fn(x);
    };

    return x;
};

// addTen(9).then(console.log)

// 4. 栈追踪与内存管理
function fooPromiseExecutor(resolve, reject) {
    setTimeout(reject, 1000, 'bar');
};

function foo1() {
    new Promise(fooPromiseExecutor);

    /*
        new Promise(
            (resolve, reject) {
                setTimeout(reject, 1000, 'bar');
            };
        );
    */
};

// foo1();



async function foo2() {
    await new Promise(fooPromiseExecutor);

    /*
        new Promise(
            (resolve, reject) {
                setTimeout(reject, 1000, 'bar');
            };
        );
    */
};

foo2();




